const Base64 = require('js-base64').Base64;
const fs = require('fs');
const path = require('path')
const system = require('./system');

let base64FilePath = path.join(system.getAppPath(),'js/base64-min.js');
const base64js = fs.readFileSync(base64FilePath, 'utf8');

function waitForCondition(checkCondition, interval = 1000) {
    return new Promise((resolve) => {
        function check() {
            if (checkCondition()) {
                resolve();
            } else {
                setTimeout(check, interval);
            }
        }
        check();
    });
}

function executeUIEventScript(processTask, uiEventScript, webContents, contextVar, callback, finalCallback) {
    // if (processTask.status == -1) {  //停止了（屏蔽了，需要登录，或者别的待处理的）
    //     let interval = setInterval(function () {  //进行空转
    //         if (processTask.status == 1) {
    //             clearInterval(interval);
    //         }
    //     }, 1000)
    // }

    //停止了（屏蔽了，需要登录，或者别的待处理的）
    waitForCondition(() => processTask.status == 1,1000)
        .then(() => {
            // console.log('条件满足，继续执行');
            var jscode = 'new Promise(function(resolve, reject) {\n' +
                ' ' + base64js + ';\n' +
                '  let contextVar = JSON.parse(\'' + JSON.stringify(contextVar) + '\');\n' +
                '  let switchProxy = false;\n' +
                '  let ban = false;\n' +
                '  let success = true;\n' +
                '  let errorStatus = 2;\n' +
                '  let result = {"success":true,"errorStatus":2};\n' +
                '  try{\n';
            jscode += 'result.data = (function(){' + uiEventScript + '})();\n' +
                '  }catch(error){\n' +
                '    //reject(error);\n' +
                '    result.success = false;\n' +
                '    result.errorStatus = -1;\n' +
                '    result.errContent = error.message;\n' +
                '  } \n' +
                '\n' +
                '  resolve(result);\n' +
                '\n' +
                '});';
            webContents.executeJavaScript(`` + jscode, true)
                .then(async (result) => {
                    result.webContentsId = webContents.id;
                    // var processTask = core.getProcessTaskByWebContentsId(webContents.id);
                    // if(processTask && processTask.currentTask && processTask.currentTask.id != taskId){  //已经切换了任务
                    //     return;
                    // }
                    if (processTask && processTask.status != 1) {  //已经停止运行
                        return;
                    }
                    // console.log('uiEventScript result='+JSON.stringify(result))
                    await callback(processTask, result);
                    if (result.success) {
                        var data = result.data;
                        if (data['next']) {
                            //异步执行，短暂休眠
                            setTimeout(function () {
                                executeUIEventScript(processTask, uiEventScript, webContents, data.data, callback, finalCallback);
                                // callback(processTask,result);
                            }, 50)
                        } else { //执行完成
                            if (processTask != null) {
                                processTask.uiEventStatus = 1;
                            }
                            finalCallback(processTask, result);
                        }
                    } else {
                        console.error(result);
                    }
                }).catch(function (e) {
                console.error('javascript error', e)
            });
        });

}


function executeExtractRequestJs(processTask, responseData, webContents, callback) {
    // let processTask = task.processTask;
    // var responseDataStr = JSON.stringify(responseData);
    // const message = "s111111";
    // ' 转义
    responseData = responseData.replace(/'/g, "\\'").replace(/\n/gm, " ");
    responseData = Base64.encode(responseData);

    var jscode = 'new Promise(function(resolve, reject) {\n' +
        ' ' + base64js + ';\n' +
        // 'let responseData = \''+responseData+'\';'+
        // 'function showMessage(msg){alert(msg)};'+
        // 'showMessage("${message}");'+
        // 'showMessage("${responseData}");'+
        // 'let responseData = base64Decode(\"'+responseData+'\");\n'+
        'let responseData = Base64.decode(\"' + responseData + '\");\n' +
        //'let responseJsonData = new Function( "return " +responseData )()\n' +    //这里不能这么转，responseData 不一定是json,可能是html,就会导致失败
        '  let switchProxy = false;\n' +
        '  let ban = false;\n' +
        '  let success = true;\n' +
        '  let errorStatus = 2;\n' +
        '  let result = {"success":true,"errorStatus":2};\n' +
        '  try{\n';

    if (processTask.switchProxyExpress) {
        jscode += 'switchProxy = (function(){' + processTask.switchProxyExpress + '})();\n';
    }
    jscode += 'if(switchProxy){\n' +
        '        result.success = false;\n' +
        '        result.errorStatus = 1;\n' +
        '        resolve(result);\n' +
        '        return;\n' +
        '    }';

    if (processTask.analyseBanExpress) {
        jscode += 'ban = (function(){' + processTask.analyseBanExpress + '})();\n';
    }
    jscode += 'if(ban){\n' +
        '        result.success = false;\n' +
        '        result.errorStatus = 0;\n' +
        '        result.errContent = "ban";\n' +
        '        resolve(result);\n' +
        '        return;\n' +
        '    }';

    if (processTask.analyseDataExpress) {
        jscode += 'result.responseAnalyseBody = (function(){' + processTask.analyseDataExpress + '})();\n';
    }
    if (processTask.storePageSource) {
        jscode += 'result.responseBody = responseData; \n';
    }

    jscode += '' +
        '  }catch(error){\n' +
        '    //reject(error);\n' +
        '    result.success = false;\n' +
        '    result.errorStatus = -1;\n' +
        //'    result.errContent = error.message;\n' +
        '    console.error(error.stack);\n' +
        '    result.errContent = error.stack;\n' +
        '  } \n' +
        '\n' +
        '    console.log(result);\n' +
        '  resolve(result);\n' +
        '\n' +
        '});';
    webContents.executeJavaScript(`` + jscode, true)
        .then((result) => {
            //console.log(result) // Will be the JSON object from the fetch call
            //先特殊值base64
            result.responseEmpty = true;  //executeExtractRequestJs 才有
            if (result.responseAnalyseBody) {
                if (!objectIsEmpty(result.responseAnalyseBody)) {
                    result.responseEmpty = false;
                }
                result.responseAnalyseBody = Base64.encode(JSON.stringify(result.responseAnalyseBody));
            }
            //暂时不需要 todo
            // if (result.responseBody) {
            //     if (typeof (result.responseBody) == 'object') {
            //
            //         result.responseBody = Base64.encode(JSON.stringify(result.responseBody));
            //     } else {
            //         result.responseBody = Base64.encode(result.responseBody.toString());
            //     }
            // }
            // result.activeInstanceId = taskData.activeInstanceId;
            // result.startTime = taskData.startTime;
            callback(result);
        });
}

function objectIsEmpty(value) {
    if (Array.isArray(value) || typeof value === 'string') {
        return value.length === 0;
    }
    if (typeof value === 'object') {
        return Object.keys(value).length === 0;
    }
    return false;
}

function executeDirtyCssSelectorExpress(webContents, dirtyCssSelectorExpress, doneCallback) {
    setTimeout(function () {
        var jscode = 'new Promise(function(resolve, reject) {\n' +
            '  let success = true;\n' +
            '  let result = {"success":true};\n' +
            '  try{\n';
        jscode += 'result.success = (function(){' + dirtyCssSelectorExpress + '})();\n' +
            '  }catch(error){\n' +
            '    //reject(error);\n' +
            '    result.success = false;\n' +
            '    result.errContent = error.message;\n' +
            '  } \n' +
            '  resolve(result);\n' +
            '});\n';
        webContents.executeJavaScript(jscode, true)
            .then((result) => {
                doneCallback(result.success);

            });
    }, 200)
}

function executeWaitCssSelectorExpress(webContents, waitCssSelectorExpress, doneCallback) {
    setTimeout(function () {
        var jscode = 'new Promise(function(resolve, reject) {\n' +
            '  let success = true;\n' +
            '  let result = {"success":true};\n' +
            '  try{\n';
        jscode += 'result.success = (function(){' + waitCssSelectorExpress + '})();\n' +
            '  }catch(error){\n' +
            '    //reject(error);\n' +
            '    result.success = false;\n' +
            '    result.errContent = error.message;\n' +
            '  } \n' +
            '  resolve(result);\n' +
            '});\n';
        webContents.executeJavaScript(jscode, true)
            .then((result) => {
                if (!result.success && result.errContent) {
                    console.error(result.errContent)
                } else if (!result.success) {
                    setTimeout(function () {
                        executeWaitCssSelectorExpress(webContents, waitCssSelectorExpress, doneCallback);
                    }, 200)

                } else {
                    doneCallback()
                }

            });
    }, 200)
}

function executeExtractHtmlJs(processTask, webContents, callback) {
    // let processTask = task.processTask;
    var jscode = 'new Promise(function(resolve, reject) {\n' +
        '  let switchProxy = false;\n' +
        '  let ban = false;\n' +
        '  let success = true;\n' +
        '  let errorStatus = 2;\n' +
        '  let result = {"success":true,"errorStatus":2};\n' +
        '  try{\n';
    if (processTask.analyseBanExpress) {
        jscode += 'variables = (function(){' + processTask.variables + '})();\n';
    }
    if (processTask.analyseExpressType == 0) {  //静态
        // if (processTask.switchProxyExpress) {
        //     jscode += 'switchProxy = (function(){' + processTask.switchProxyExpress + '})();\n';
        // }
        jscode += 'if(switchProxy){\n' +
            '        result.success = false;\n' +
            '        result.errorStatus = 1;\n' +
            '        resolve(result);\n' +
            '        return;\n' +
            '    }\n';

        if (processTask.analyseBanExpress) {
            jscode += 'ban = (function(){' + processTask.analyseBanExpress + '})();\n';
        }
        jscode += 'if(ban){\n' +
            '        result.success = false;\n' +
            '        result.errorStatus = 0;\n' +
            '        result.errContent = "ban";\n' +
            '        resolve(result);\n' +
            '        return;\n' +
            '    }\n';


        if (processTask.analyseExpress) {
            jscode += 'result.responseAnalyseBody = (function(){' + processTask.analyseExpress + '})();\n';
        }
        if (processTask.storePageSource) {
            jscode += 'result.responseBody = document.documentElement.outerHTML;\n';
        }
        jscode += 'resolve(result);\n';
    } else {  //动态，由express 调用 resolve
        jscode += processTask.analyseExpress + ';\n';
    }
    jscode += '' +
        '  }catch(error){\n' +
        '    //reject(error);\n' +
        '    result.success = false;\n' +
        '    result.errorStatus = -1;\n' +
        '    result.errContent = error.message;\n' +
        '  resolve(result);\n' +
        '  } \n' +
        '});\n';

    let executeAnalyseExpressJs = function () {
        webContents.executeJavaScript(jscode, true)
            .then((result) => {
                //console.log(result) // Will be the JSON object from the fetch call
                //先特殊值base64
                if (result.responseAnalyseBody) {
                    result.responseAnalyseBody = Base64.encode(JSON.stringify(result.responseAnalyseBody));
                }
                if (result.responseBody) {
                    result.responseBody = Base64.encode(result.responseBody);
                }
                // result.id = task.id;
                // result.activeProcessId = processTask.activeProcessId;
                // result.startTime = task.startTime;
                callback(result);
            });
    }
    if (processTask.waitCssSelectorExpress) {
        executeWaitCssSelectorExpress(webContents, processTask.waitCssSelectorExpress, function () {
            executeAnalyseExpressJs();
        });

    } else {
        executeAnalyseExpressJs();
    }

}

// 导出模块函数
module.exports = {
    executeExtractHtmlJs,
    executeUIEventScript,
    executeExtractRequestJs,
};
